package com.baidu.unlockdemo.customview

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.core.animation.addListener

class LoginButton : View {
    private var mWidth = dp2pxF(200)
    private var mHeight = dp2pxF(60)

    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        var widthSize = MeasureSpec.getSize(widthMeasureSpec)

        if (widthMode != MeasureSpec.EXACTLY) {
            widthSize = mWidth.toInt()
        }

        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)

        if (heightMode != MeasureSpec.EXACTLY) {
            heightSize = mHeight.toInt()
        }

        if (widthSize < heightSize){
            var temp = widthSize
            widthSize = heightSize
            heightSize = temp
        }
        setMeasuredDimension(widthSize, heightSize)
    }

    /*
    动画的本质就是不断改变控件绘制时某个属性值，
    然后调用invalidate()方法
    通知系统重新绘制

    1.寻找动画因子
    2.定义一个变量记录动画因子的值
    3.思考这个值的变化是由内部来决定还是外部来决定
      下载数据由外部出来进度
      如果是由自己来操作，那么自己重写onTouchEvent方法触发ValueAnimator动画
    4.给外部提供改变动画因子的方法
     */

    private val mPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#00BAAD")
        style = Paint.Style.FILL
    }
    //半圆效果由内部决定
    private var mCornerRadius = 0f
    private var mMaxCornerRadius = 0f
    //中间缩放是由下载进度决定
    private var mOffsetX = 0f
    private var mMaxOffsetX = 0f

    private var mCallBack:()->Unit = {}
    //外部监听事件
    fun addOnClickCallback(callback:()->Unit){
        //保存函数变量
        mCallBack = callback
    }

    //提供外部修改进度
    fun setProgress(progress: Float){
        mOffsetX = mMaxOffsetX * progress
        invalidate()
    }

    /*
     在onSizeChanged方法中获取控件的宽高
     这个方法在onMeasure之后会被调用
     */
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mMaxCornerRadius = measuredHeight/2f
        mMaxOffsetX = measuredWidth/2 - mMaxCornerRadius
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        canvas.drawRoundRect(
            mOffsetX,
            0f,
            measuredWidth.toFloat() - mOffsetX,
            measuredHeight.toFloat(),
            mCornerRadius,
            mCornerRadius,
            mPaint
        )
    }

    /**
     * 使用by lazy实现调用时才创建
     */
    private val mCornerAnimator:ValueAnimator by lazy {
        ValueAnimator.ofFloat(0f, mMaxCornerRadius).apply {
            duration = 1000
            addUpdateListener {
                mCornerRadius = it.animatedValue as Float
                invalidate()
            }
            addListener(onEnd = {
                //回调事件
                mCallBack()
                mOnClickListener?.let {
                    it.onClick()
                }
            })
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if(event?.action == MotionEvent.ACTION_DOWN) {
            if (mCornerAnimator.isRunning || mCornerAnimator.isStarted)
                return true

            mCornerAnimator.start()
        }
        return true
    }


    /**
     定义一个变量保存外部监听者的对象
     */
    private var mOnClickListener: IOnAnimBtnClickListener? = null

    /**
       给外部提供设置监听的方法
     */
    fun setIOnClickListener(listener: IOnAnimBtnClickListener) {
        mOnClickListener = listener
    }

    /*
    使用接口回调事件
     */
    interface IOnAnimBtnClickListener{
        fun onClick()
    }
}